<?php if (!defined('__FW_RUN__')) exit('not found');
/**
 * conf.func.php
 *
 * 범용 함수를 관리합니다.
 * _ 로 시작하는 함수는 숨겨진 기능을 하는 private 속성의 함수입니다.
 *
 * @package conf
 * @author  Platform Team
 */

$f = FW_DIR_PROJECT . '/conf/conf.func.php';
if (is_file($f)) {
    include $f;
}

$f = FW_DIR_MIDDLEWORK . '/conf/conf.func.php';
if (FW_MIDDLEWORK_USE && is_file($f)) {
    include $f;
}

/**
 * 실행 타임 반환
 *
 * @return float
 */
function getMicrotime()
{
    list($usec, $sec) = explode(' ', microtime());
    return ((float)$usec + (float)$sec);
}

/**
 * 시스템 메모리 사용량 최대치 반환
 *
 * return string
 */
function getMemoryPeakUsage()
{
    $size = memory_get_peak_usage(true);
    $unit = array('b','kb','mb','gb','tb','pb');
    return round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i].' ('.$size.')';
}

/**
 * 모든 MIME 타입 반환
 *
 * @return array
 */
function getMimes()
{
    $aTypes = array(
        'txt' => 'text/plain',
        'htm' => 'text/html',
        'html' => 'text/html',
        'php' => 'text/html',
        'css' => 'text/css',
        'js' => 'application/javascript',
        'json' => 'application/json',
        'xml' => 'application/xml',
        'swf' => 'application/x-shockwave-flash',
        'flv' => 'video/x-flv',

        // images
        'png' => 'image/png',
        'jpe' => 'image/jpeg',
        'jpeg' => 'image/jpeg',
        'jpg' => 'image/jpeg',
        'gif' => 'image/gif',
        'bmp' => 'image/bmp',
        'ico' => 'image/vnd.microsoft.icon',
        'tiff' => 'image/tiff',
        'tif' => 'image/tiff',
        'svg' => 'image/svg+xml',
        'svgz' => 'image/svg+xml',

        // archives
        'zip' => 'application/zip',
        'rar' => 'application/x-rar-compressed',
        'exe' => 'application/x-msdownload',
        'msi' => 'application/x-msdownload',
        'cab' => 'application/vnd.ms-cab-compressed',

        // audio/video
        'mp3' => 'audio/mpeg',
        'wav' => 'audio/mpeg',
        'wma' => 'audio/mpeg',
        'qt' => 'video/quicktime',
        'mov' => 'video/quicktime',

        // adobe
        'pdf' => 'application/pdf',
        'psd' => 'image/vnd.adobe.photoshop',
        'ai' => 'application/postscript',
        'eps' => 'application/postscript',
        'ps' => 'application/postscript',

        // ms office
        'doc' => 'application/msword',
        'rtf' => 'application/rtf',
        'xls' => 'application/vnd.ms-excel',
        'ppt' => 'application/vnd.ms-powerpoint',

        // open office
        'odt' => 'application/vnd.oasis.opendocument.text',
        'ods' => 'application/vnd.oasis.opendocument.spreadsheet'
    );

    return $aTypes;
}

/**
 * 타입명에 의한 MIME 타입을 반환
 *
 * @param string $sType
 * @return string | false
 */
function getMime($sType)
{
    $sType = trim(strtolower($sType));
    $aMime = getMimes();

    return isset($aMime[$sType]) ? $aMime[$sType] : false;
}

/**
 * 파일의 확장자에 맞는 MIME 타입을 반환
 *
 * @param string $sFilename
 * @return string
 */
function getFileMimeType($sFilename)
{
    $aTypes = getMimes();
    $sExt = trim(strtolower(array_pop(explode('.', $sFilename))));

    if (array_key_exists($sExt, $aTypes)) {
        return $aTypes[$sExt];
    } else {
        return 'application/octet-stream';
    }
}

/**
 * 접속한 클라이언트의 실제 아이피 주소 반환
 *
 * @return string
 */
function getClientRealIp()
{
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        return $_SERVER['HTTP_X_FORWARDED_FOR'];
    }

    if (isset($_SERVER['HTTP_CLIENT_IP'])) {
        return $_SERVER['HTTP_CLIENT_IP'];
    }

    return $_SERVER['REMOTE_ADDR'];
}

/**
 * 읽어들이는 파일을 지정한 문자인코딩으로 변환해서 반환
 *
 * @param string $sPath
 * @param string $sToEncoding
 */
function getFileContentsAutoIconv($sPath, $sToEncoding=FW_CHARSET)
{
    if (!is_file($sPath)) return false;

    $ENCODE_UTF8_BOM = chr(0xEF).chr(0xBB).chr(0xBF);
    $ENCODE_UTF16_BE = chr(0xFE).chr(0xFF);
    $ENCODE_UTF16_LE = chr(0xFF).chr(0xFE);
    $ENCODE_UTF32_BE = chr(0x00).chr(0x00).chr(0xFE).chr(0xFF);
    $ENCODE_UTF32_LE = chr(0xFF).chr(0xFE).chr(0x00).chr(0x00);

    $content = file_get_contents($sPath);


    if (strpos($content, $ENCODE_UTF8_BOM) === 0) {

        $content = preg_replace('/^'.$ENCODE_UTF8_BOM.'/', '', $content);
        $content = mb_convert_encoding($content, $sToEncoding, 'UTF-8');

    } else if (strpos($content, $ENCODE_UTF16_BE) === 0) {

        $content = preg_replace('/^'.$ENCODE_UTF16_BE.'/', '', $content);
        $content = mb_convert_encoding($content, $sToEncoding, 'UTF-16BE');

    } else if (strpos($content, $ENCODE_UTF16_LE) === 0) {

        $content = preg_replace('/^'.$ENCODE_UTF16_LE.'/', '', $content);
        $content = mb_convert_encoding($content, $sToEncoding, 'UTF-16LE');

    } else if (strpos($content, $ENCODE_UTF32_BE) === 0) {

        $content = preg_replace('/^'.$ENCODE_UTF32_BE.'/', '', $content);
        $content = mb_convert_encoding($content, $sToEncoding, 'UTF-32BE');

    } else if (strpos($content, $ENCODE_UTF32_LE) === 0) {

        $content = preg_replace('/^'.$ENCODE_UTF32_LE.'/', '', $content);
        $content = mb_convert_encoding($content, $sToEncoding, 'UTF-32LE');

    } else {

        $encoding = mb_detect_encoding($content, 'UTF-8, EUC-KR, ISO-8859-1');
        if ($encoding !== false && $encoding != $sToEncoding) {
            $content = mb_convert_encoding($content, $sToEncoding, $encoding);
        }

    }

    return $content;
}

/**
 * 모든 원소에 대해 stripslaches 를 실행
 *
 * @param mixed $mValue (배열 혹은 문자열)
 * @return mixed
 */
function stripslashesDeep($mValue)
{
    if (is_array($mValue)) {
        foreach ($mValue as $key => $value) {
            $mValue[$key] = stripslashesDeep($value);
        }
    } else if (is_string($mValue)) {
        $mValue = stripslashes($mValue);
    }

    return $mValue;
}

/**
 * 모든 원소에 대한 인코딩 컨버트
 *
 * @param mixed $mValue
 * @param string $sIn       (기본 : EUC-KR)
 * @param string $sOut      (기본 : UTF-8)
 * @param string $sOption
 * @return mixed
 */
function iconvDeep($mValue, $sIn='EUC-KR', $sOut='UTF-8', $sOption='//IGNORE//TRANSLIT')
{
    $aEnc = array(
        'in'  => $sIn,
        'out' => $sOut.$sOption
    );

    if (is_array($mValue) === true) array_walk_recursive($mValue, '_iconv', $aEnc);
    else _iconv($mValue, null, $aEnc);

    return $mValue;
}

/**
 * iconv for array_walk_recursive
 *
 * @param mixed &$mItem 인코딩 변경할 문자열 값 (call by reference)
 * @param mixed $mKey  array_walk_recursive 로 들어오는 배열의 키
 * @param array $aEnc  변경할 인코딩 값 (in / out)
 */
function _iconv(&$mItem, $mKey, $aEnc)
{
    if (is_string($mItem) == true) $mItem = iconv($aEnc['in'], $aEnc['out'], $mItem);
}

/**
 * alias - Router
 *
 * @return Router
 */
function r()
{
    return Router::instance();
}

/**
 * alias - Model
 *
 * @param   string    $sName        (풀클래스명)
 * @param   array     $aDsn         (DSN 정보)
 * @return  mixed (object | false)
 */
function m($sName, $aDsn=null)
{
    return Model::instance()->load($sName, $aDsn);
}

/**
 * alias - Session
 *
 * @return Session
 */
function s()
{
    return Session::instance();
}

/**
 * alias - Debug
 */
function d()
{
    $aLocation = null;
    if (function_exists('xdebug_call_file')) {
        $aLocation['file'] = xdebug_call_file();
        $aLocation['line'] = xdebug_call_line();
    }

    coreDebugCommon::setDeveloperMsg(func_get_args(), $aLocation);
}

/**
 * alias - Error (=trigger_error)
 * @param string $sMsg error message
 * @param int $itype error no
 * */
function e($sMsg, $iType=E_USER_NOTICE)
{
    if (function_exists('xdebug_get_function_stack')) {
        $aFuncStack = xdebug_get_function_stack();
        $iCnt = count($aFuncStack)-1;
        coreDebugError::$aLocation['file'] = $aFuncStack[$iCnt]['file'];
        coreDebugError::$aLocation['line'] = $aFuncStack[$iCnt]['line'];
    }
    coreDebugError::setData($sMsg, $iType);
}

/**
 * alias - Uipack
 *
 * @param string $sName (드라이버명)
 * @return utilUipackDriver
 */

function Ui($sName)
{
    return Uipack::driver($sName);
}

/**
 * alias - Exception (핸들러와 동일)
 * @param Exception 예외 객체
 * @deprecated
 */
function except($oException)
{
    coreDebugException::setData($oException);
}

/**
 * Exception Handler
 *
 * @access private
 */
function _exceph($oException)
{
    except($oException);
}

/**
 * Shut Down Handler
 *
 * @access private
 */
function _shutd()
{
    coreDebug::show();
}

/**
 * 기본제공 혹은 사용자 정의형 드라이버명 반환
 *
 * !!NOTICE!!
 * 일반적으로 프레임워크내  각종 클래스 드라이버명은 규칙적으로 정해져 있으나 이외 어플리케이션 레벨에서
 * 사용하기 위해 만들어진 특수한 드라이버를 로드하기위한  클래스명을 파악하여 반환하는 역할을 한다.
 * [:클래스명] 이런식으로 작성된 설정은 클래스명을 바로 반환하도록 한다.
 * 이외에는 정해진 규칙에 의해 클래스명을 반환한다.
 *
 * !!WARNING!!
 * 프레임워크 레벨 이외에는 해당 함수를 호출하는 것은 권장하지 않는 사항.
 *
 *
 * @param string $sName            (드라이버명)
 * @param string $sDefaultPrefix   (기본 클래스 드라이버 접두어) - : 문자로 시작하지 않을때 앞에 할당되는 문자열
 * @return string
 */
function _getTypedefDriverName($sName, $sDefaultPrefix)
{
    if (strpos($sName, ':') === 0) {
        $sClass = substr($sName, 1);
    } else {
        $sName = ucfirst($sName);
        $sClass = $sDefaultPrefix . $sName;
    }

    return $sClass;
}

/**
 * 템플릿함수 - 쿼리문 컨버팅
 *
 * 사용지점
 * coreModelDbDriverCommon::query
 * coreModelDbDriverCommon::exec
 *
 * @return string
 */
if (!function_exists('T_dbQueryConvert')) {
    function T_dbQueryConvert($sSql)
    {
        return $sSql;
    }
}

/**
 * 템플릿함수 - 쿼리문 추가 문자열
 * 반환되는 문자열을 기존 쿼리문에 덧붙여 실행하고 싶을 경우 사용
 *
 * 사용지점
 * coreModel::query
 *
 * @param string $sClassName (호출된 모델 클래스명이 전달됨)
 * @return string
 */
if (!function_exists('T_dbQueryAppend')) {
    function T_dbQueryAppend($sClassName)
    {
        return '';
    }
}

/**
 * 템플릿함수 - 쿼리 결과 데이터 컨버팅
 *
 * 사용지점
 * coreModelDbDriverCommon::query
 *
 * @return mixed
 */
if (!function_exists('T_dbDataConvert')) {
    function T_dbDataConvert($mResult)
    {
        return $mResult;
    }
}

/**
 * 템플릿함수 - 쿼리 EXEC 타입의 실행 비활성화
 *
 * 사용지점
 * coreModel::query
 */
if (function_exists('T_dbQueryExecDisabled') === false) {
    function T_dbQueryExecDisabled()
    {
        echo 'can not execute query(insert|update|delete|EXEC TYPE)';
        exit;
    }
}

/**
 * 템플릿 함수 - 디버그 권한 체크
 *
 * true : 권한 있음
 * false : 권한 없음
 *
 * 사용지점
 * coreDebug::isPossbibleDebug
 *
 * @return boolean
 */
if (!function_exists('T_debugPossible')) {
    function T_debugPossible()
    {
        $aIp = explode('.', $_SERVER['REMOTE_ADDR']);

        // 대역대 /16
        $sIp = $aIp[0].'.'.$aIp[1].'.';
        $aIpClass = array('192.168.');

        if (in_array($sIp, $aIpClass)) {
            return true;
        }

        // 대역대 /24
        $sIp = $aIp[0].'.'.$aIp[1].'.'.$aIp[2].'.';
        $aIpClass = array('123.140.248.', '123.140.249.', '203.231.63.', '115.92.147.', '211.63.40.');

        if (in_array($sIp, $aIpClass)) {
            return true;
        }

        //
        // 대역대 /32
        // 보안로그인, PG관련 아이피는 패스,
        // 회사외 외부아이피 : 203.231.63.251 (김형숙), 203.231.63.252 (원동환)
        //
        $aIgnoreIps = array('127.0.0.1', '220.73.160.28', '222.122.39.124', '222.122.39.154', '203.231.63.251', '203.231.63.252');
        if (in_array($_SERVER['REMOTE_ADDR'], $aIgnoreIps)) {
            return true;
        }

        //
        // 쉘 모드에서 테스트할 경우 $_SERVER['REMOTE_ADDR'] 정보가 없으므로 추가된 코드
        //
        if (is_array($_SERVER['argv'])) {
            foreach ($_SERVER['argv'] as $v) {
                if (strpos($v, 'phpunit')) {
                    return true;
                }
            }
        }

        // 권한 없음
        return false;
    }
}

/**
 * 국제화 - 현재 도메인의 메세지 반환
 * !!NOTICE!!
 * array, object 등 유효하지 않은 파라미터는 null 을 반환하나 warning 레벨의 에러가 발생하는것에 주의
 *
 * @param string $sMsg
 * @return string
 */
function __($sMsg)
{
    if ($sMsg === null || $sMsg === false || $sMsg === '') {
        return '';
    }

    return gettext($sMsg);
}

/**
 * 국제화 - 현재 도메인의 메세지 반환(복수형)
 * !!NOTICE!!
 * array, object 등 유효하지 않은 파라미터는 null 을 반환하나 warning 레벨의 에러가 발생하는것에 주의
 *
 * @param string $sMsg1
 * @param string $sMsg2
 * @param int $iCnt
 * @return string
 */
function __n($sMsg1, $sMsg2, $iCnt)
{
    if ($sMsg1 === null || $sMsg1 === false || $sMsg1 === '') {
        return '';
    }

    if ($sMsg2 === null || $sMsg2 === false || $sMsg2 === '') {
        return '';
    }

    return ngettext($sMsg1, $sMsg2, $iCnt);
}

/**
 * 국제화 - 지정한 도메인의 메세지 반환
 * !!NOTICE!!
 * array, object 등 유효하지 않은 파라미터는 null 을 반환하나 warning 레벨의 에러가 발생하는것에 주의
 *
 * @param string $sDomain
 * @param string $sMsg
 * @return string
 */
function __d($sDomain, $sMsg)
{
    if ($sMsg === null || $sMsg === false || $sMsg === '') {
        return '';
    }

    return dgettext($sDomain, $sMsg);
}

/**
 * 국제화 - 지정한 도메인의 메세지 반환(복수형)
 * !!NOTICE!!
 * array, object 등 유효하지 않은 파라미터는 null 을 반환하나 warning 레벨의 에러가 발생하는것에 주의
 *
 * @param string $sDomain
 * @param string $sMsg1
 * @param string $sMsg2
 * @param int $iCnt
 * @return string
 */
function __dn($sDomain, $sMsg1, $sMsg2, $iCnt)
{
    if ($sMsg1 === null || $sMsg1 === false || $sMsg1 === '') {
        return '';
    }

    if ($sMsg2 === null || $sMsg2 === false || $sMsg2 === '') {
        return '';
    }

    return dngettext($sDomain, $sMsg1, $sMsg2, $iCnt);
}